package com.qf.smsplatform.webmaster.service.impl;


import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.qf.smsplatform.webmaster.cache.AllowParamsCache;
import com.qf.smsplatform.webmaster.cache.SmsTempCache;
import com.qf.smsplatform.webmaster.constans.ResultCode;
import com.qf.smsplatform.webmaster.events.updateSmsEvent;
import com.qf.smsplatform.webmaster.exceptions.AddDataException;
import com.qf.smsplatform.webmaster.exceptions.UpdateDataException;
import com.qf.smsplatform.webmaster.mapper.SmsTempMapper;
import com.qf.smsplatform.webmaster.pojo.CheckType;
import com.qf.smsplatform.webmaster.pojo.MyAuthUser;
import com.qf.smsplatform.webmaster.pojo.TAllowParams;
import com.qf.smsplatform.webmaster.pojo.TSmsTemplate;
import com.qf.smsplatform.webmaster.service.SmsTempService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional
public class SmsTempServiceImpl implements SmsTempService {
    private SmsTempMapper smsTempMapper;
    private SmsTempCache smsTempCache;
    private ApplicationContext context;
    private AllowParamsCache allowParamsCache;

    @Autowired
    public void setAllowParamsCache(AllowParamsCache allowParamsCache){
        this.allowParamsCache = allowParamsCache;
    }

    @Autowired
    public void setSmsTempMapper(SmsTempMapper smsTempMapper) {
        this.smsTempMapper = smsTempMapper;
    }

    @Autowired
    public void setContext(ApplicationContext context) {
        this.context = context;
    }

    @Autowired
    public void setSmsTempCache(SmsTempCache smsTempCache) {
        this.smsTempCache = smsTempCache;
    }


    @Override//添加
    public int add(TSmsTemplate tSmsTemplate) {
        if (tSmsTemplate.isNull(CheckType.ADD)) {
            throw new AddDataException("必须传递的数据没有传递", ResultCode.DATA_ISNULL);
        }
        smsTempMapper.addTemp(tSmsTemplate);
        return 0;
    }

    @Override//查询所有
    public PageInfo<TSmsTemplate> findAll(int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        //先从缓存中获取所有数据
        List<TSmsTemplate> allDate = smsTempCache.getAllData();
        //加载当前用户
        MyAuthUser user = (MyAuthUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        //判断是不是当前用户创建的
        List<TSmsTemplate> collect = allDate.stream().filter(tSmsTemplate -> {
            return tSmsTemplate.getOwntype() == 1 || tSmsTemplate.getCreater() == user.getId() || user.getType() == 1;
        }).collect(Collectors.toList());
        List<TSmsTemplate> collect1 = collect.stream().skip((pageNum - 1) * pageSize).limit(pageSize).collect(Collectors.toList());

        PageInfo<TSmsTemplate> pageInfo = new PageInfo<>(collect1);
        pageInfo.setTotal(collect.size());
        return pageInfo;
    }

    @Override//修改
    public void update(TSmsTemplate tSmsTemplate) {
        if (tSmsTemplate.isNull(CheckType.UPDATE)) {
            throw new UpdateDataException("必须传递的值没有传递", ResultCode.NO_PERMISSON);
        }
        TSmsTemplate tSmsTemplate1 = smsTempMapper.selectById(tSmsTemplate.getId());
        if (tSmsTemplate.getOwntype() != 1 && tSmsTemplate.getCreater() != tSmsTemplate1.getCreater()) {
            throw new UpdateDataException("您没有权限更改这条数据", ResultCode.NO_PERMISSON);
        }
        smsTempMapper.update(tSmsTemplate);
        context.publishEvent(new updateSmsEvent());

    }

    @Override//删除
    public void delete(List<Integer> id) {
        MyAuthUser user = (MyAuthUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (user.getType() == 1) {
            smsTempMapper.Admindelete(id);
        } else {
            smsTempMapper.deletes(id);
        }
        context.publishEvent(new updateSmsEvent());
    }

    @Override   //动态查询
    public List<TSmsTemplate> DynamicQuery(TSmsTemplate tSmsTemplate) {

        TAllowParams sms = allowParamsCache.getHashCache().get("sms");
        String owntype = sms.getParam1();
        String creater = sms.getParam2();
        String status = sms.getParam3();
        List<String> allowParams = new ArrayList<>();
        if (owntype != null) {
            allowParams.add(owntype);
        }
        if (creater != null) {
            allowParams.add(creater);
        }
        if (status != null) {
            allowParams.add(status);
        }

        TSmsTemplate instance = null;
        try {
            Class<? extends TSmsTemplate> smsTemplateClass = tSmsTemplate.getClass();
            instance = smsTemplateClass.newInstance();
            TSmsTemplate finalInstance = instance;
            allowParams.forEach(name -> {
                //从传递的参数据对象中取出来我们需要的参数,设置给我们新创建的对象
                PropertyDescriptor propertyDescriptor = null;//从指定类中获取指定名字的属性
                try {
                    propertyDescriptor = new PropertyDescriptor(name, smsTemplateClass);
                } catch (IntrospectionException e) {
                    e.printStackTrace();
                }
                Method readMethod = propertyDescriptor.getReadMethod();//读方法 就是 get 方法
                Method writeMethod = propertyDescriptor.getWriteMethod();//写方法就是 set 方法
                try {
                    writeMethod.invoke(finalInstance, readMethod.invoke(tSmsTemplate));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            });
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        System.err.println(instance);

        List<TSmsTemplate> list = smsTempMapper.findByMultiParam(instance);
        return list;
    }
}
